import 'package:family_expense/features/account_user/models/account_group.dart';
import 'package:family_expense/features/account_user/services/account_group_service.dart';
import 'package:family_expense/features/account_user/services/account_group_user_service.dart';
import 'package:family_expense/features/account_user/widgets/user_shared.dart';
import 'package:family_expense/features/bank_card/services/bank_card_service.dart';
import 'package:family_expense/features/income_expense_detail_type/services/income_expense_detail_type_loader.dart';
import 'package:family_expense/features/income_expense_search/widgets/income_expense_search_home.dart';
import 'package:family_expense/main_view.dart';
import 'package:flutter/material.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:my_flutter_core/my_flutter_core.dart';

class HomeViewAppBar extends MyAppBarBase {
  HomeViewAppBar({super.actionCallback});

  final AccountGroupUserService _accountGroupUserService =
      AccountGroupUserService();

  final AccountGroupService _accountGroupService = AccountGroupService();
  final AuthService _authService = AuthService();
  final BankCardService _bankCardService = BankCardService();

  late BuildContext _context;

  @override
  AppBar getAppBar(BuildContext context) {
    _context = context;

    return AppBar(
      leading: IconButton(
        icon: Icon(MdiIcons.homeSwitchOutline),
        onPressed: () => _showAvailableAccountGroups(),
      ),
      title: _buildAppBarTitle(),
      actions: <Widget>[
        IconButton(
          icon: const Icon(Icons.search),
          onPressed: () async {
            // DO NOT use BuildContext across asynchronous gaps.
            // That's why async/await cannot be used here.
            // https://dart-lang.github.io/linter/lints/use_build_context_synchronously.html
            final dataUpdated = await NavigatorHelper.push<bool>(
              _context,
              const IncomeExpenseSearchHome(),
            );

            if (context.mounted && dataUpdated == true) {
              // Pops all pages and returns to the main view.
              // The route is [MainView] -> [EditIncomeExpense] -> [MainView].
              // [MainView] is the last page of the app. That's why need to pop all pages.
              NavigatorHelper.pushAndRemoveUntil(
                _context,
                const MainView(),
                (route) => false,
              );
            }
          },
        ),
      ],
    );
  }

  Widget _buildAppBarTitle() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          _accountGroupService.currentAccountGroup?.isOwner == false
              ? '${_accountGroupService.currentAccountGroup?.ownerFullName ?? ''}的账户'
              : '我的账户',
        ),
        const SizedBox(height: 2.0),
        Text(
          _accountGroupService.currentAccountGroup!.ownerUsername!
              .formatMobilePhoneNumber(),
          style: const TextStyle(fontSize: 10.0),
        ),
      ],
    );
  }

  Widget _buildOwnerUsername(User user, AccountGroup accountGroup) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Text(accountGroup.ownerUsername!.formatMobilePhoneNumber()),
        if (user.id == accountGroup.ownerId)
          Container(
            margin: const EdgeInsets.only(left: 4.0),
            child: const InfoChip(
              text: '我自己',
              textColor: Colors.black87,
              backgroundColor: Colors.amber,
            ),
          ),
      ],
    );
  }

  /// Builds to show user full name info.
  Widget _buildListTileTrailing(User user, AccountGroup accountGroup) {
    if (user.accountGroupId == accountGroup.id) {
      return const InfoChip(
        text: '使用中',
        textColor: Colors.white,
        backgroundColor: Colors.blueAccent,
      );
    } else if (accountGroup.ownerId != user.id) {
      return TextButton(
        child: const Text('退出账户', style: TextStyle(color: Colors.orange)),
        onPressed: () => _quit(accountGroup),
      );
    }

    return const SizedBox(width: 1.0);
  }

  void _quit(AccountGroup accountGroup) {
    showConfirmDialog(
      _context,
      '退出 ${accountGroup.ownerFullName} (${accountGroup.ownerUsername!.formatMobilePhoneNumber()}) 的账户组吗？退出账户组不会删除任何数据。',
      onConfirm: () async {
        // Shows the overlay during switching.
        showInProgressOverlay(_context, message: '正在处理');

        await _accountGroupUserService.quit(accountGroup.id!);

        if (_context.mounted) {
          // Cloeses processing overlay.
          NavigatorHelper.pop(_context);

          // Closes bottom sheet.
          NavigatorHelper.pop(_context);
        }

        // Shows the result.
        showToast(
          '已退出 ${accountGroup.ownerFullName} (${accountGroup.ownerUsername!.formatMobilePhoneNumber()}) 的账户组。',
        );
      },
    );
  }

  /// Shows available account groups for switching.
  Future<void> _showAvailableAccountGroups() async {
    // Why query api each time the switch button tapped?
    // Because we need to be sure show latest available account group list.
    // Just in case user is removed from some account groups when he/she is browsing [HomeView].
    final list = await _accountGroupUserService.queryAvailableAccountGroups();

    final user = await AuthStateService.instance.currentUser;

    if (_context.mounted) {
      showModalBottomSheet<void>(
        context: _context,
        builder: (context) {
          return SizedBox(
            height: 270.0,
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                const SizedBox(height: 15.0),
                const Text('切换账户组', style: TextStyle(fontSize: 18.0)),
                const SizedBox(height: 10.0),
                Expanded(
                  child: ListView(
                    children: list.map((e) {
                      return ListTile(
                        selected: user!.accountGroupId == e.id,
                        leading: UserAvatorView(
                          User(avatarUrl: e.ownerAvatarUrl),
                        ),
                        title: Text(e.ownerFullName!),
                        subtitle: _buildOwnerUsername(user, e),
                        trailing: _buildListTileTrailing(user, e),
                        onTap: user.accountGroupId != e.id
                            ? () => _switchAccountGroup(e)
                            : null,
                      );
                    }).toList(),
                  ),
                ),
              ],
            ),
          );
        },
      );
    }
  }

  /// Switches to selected account group.
  Future<void> _switchAccountGroup(AccountGroup accountGroup) async {
    // Shows the overlay during switching.
    showInProgressOverlay(_context, message: '正在切换');
    final res = await _authService.switchAccountGroup(accountGroup.id!);
    await _saveSwitchedInfo(res, accountGroup);

    if (_context.mounted) {
      // Cloeses switching overlay.
      NavigatorHelper.pop(_context);

      // Closes bottom sheet.
      NavigatorHelper.pop(_context);
    }
  }

  /// Saves switched account group info.
  Future<void> _saveSwitchedInfo(
    Map<String, dynamic> res,
    AccountGroup accountGroup,
  ) async {
    // Converts the server data to user instance.
    final user = User.fromJson(res);

    final authenticationService = AuthStateService.instance;

    // Saves the user data retrieved from server.
    authenticationService.saveUserInfo(user);

    // Converts the server data to token instance.
    final token = Token.fromServerJson(res);

    // Saves the token data retrieved from server.
    await TokenService.saveToken(token);

    // Checks if current user is in collection. If it is that means current users enabled quick action.
    // We just update the user and token data in the collection just in case the server refreshed the token.
    if (await authenticationService.isUserInCollection(user)) {
      authenticationService.saveUserToCollection(user);
      TokenService.saveTokenForUserInCollection(user);
    }

    _accountGroupService.currentAccountGroup = accountGroup;

    // Re-init for new account group.
    IncomeExpenseDetailTypeLoader.clearCache();
    await IncomeExpenseDetailTypeLoader.init();

    await _bankCardService.reInit();

    final msg = accountGroup.isOwner == true
        ? '已切换回我自己的账户'
        : '已切换至 ${accountGroup.ownerFullName} 的账户';

    showToast(msg);
    super.actionCallback?.call(user);
  }
}
